/*
 * @Author: 火红色祥云 809880192@qq.com
 * @Date: 2023-09-03 18:10:56
 * @LastEditors: 火红色祥云 809880192@qq.com
 * @LastEditTime: 2023-09-07 20:50:31
 * @FilePath: /imx6ull-app/23_uart/uart.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
/*
tcflush(int fd, int queue_selector)：
刷新给定文件描述符fd关联的输入或输出队列。queue_selector参数可以是TCIFLUSH（刷新输入队列），TCOFLUSH（刷新输出队列）或TCIOFLUSH（刷新输入和输出队列）之一。
tcdrain(int fd)：等待所有输出数据被传输完成后再返回。该函数保证了数据已经被完全发送出去。
tcsendbreak(int fd, int duration)：发送一个断线信号（break signal）到给定文件描述符fd。duration参数指定断线信号的持续时间。
*/
int uart_init(const char *device)
{
    int fd;
    struct termios serial;
    
    // 打开串口设备文件
    fd = open(device, O_RDWR | O_NOCTTY);
    if (fd == -1) {
        perror("无法打开串口设备");
        return -1;
    }
    
    // 配置串口
    /*获取给定文件描述符fd关联的终端设备参数，并将其保存在termios结构体中。*/
    tcgetattr(fd, &serial);
    /*将终端参数设置为原始模式，禁用输入和输出处理以及对特殊字符的解释。*/
    cfmakeraw(&serial); // 将串口设为原始模式
    /*设置输入波特率。speed参数表示要设置的波特率值*/
    cfsetispeed(&serial, B9600); // 设置输入波特率为9600
    /*设置输出波特率。speed参数表示要设置的波特率值*/
    cfsetospeed(&serial, B9600); // 设置输出波特率为9600
    /*设置给定文件描述符fd关联的终端设备参数，使用termios结构体中的值。optional_actions参数指定何时应用修改后的参数。*/
    tcsetattr(fd, TCSANOW, &serial);
    
    return fd;
}

int uart_send(int fd, char *buffer, int size)
{
    // 向串口发送数据
    int num_bytes = write(fd, buffer, size);
    if (num_bytes == -1) {
        perror("无法向串口发送数据");
        return -1;
    }
    
    return num_bytes;
}

int uart_recv(int fd, char *buffer, int size)
{
    // 从串口接收数据
    int num_bytes = read(fd, buffer, size);
    int i=0;
    if (num_bytes > 0) {
        printf("num_bytes:%d\r\n",num_bytes);
        for (i = 0; i < num_bytes; i++)
        {
            printf("%02x\r",buffer[i]);
        }
        
    } else {
        perror("无法从串口接收数据");
    }
    printf("\n");
    return num_bytes;
}
